package src

import (
	"fmt"
	"net/http"
	"reflect"
	"sort"
	"strings"
	"sync"
)

var FilterMap sync.Map

// 用来存储全局过滤器
func RegisterFilter(name string, filter FilterFactory) {
	FilterMap.Store(name, filter)
}

// 定义个类型，是一个方法
type GatewayFilter func(exchange *ServerWebExchange) ResponseFilter

type ResponseFilter func(*http.Response)
type ResponseFilters []ResponseFilter

// 执行response
func (filters ResponseFilters) Filter(response *http.Response) {
	for _, f := range filters {
		f(response)
	}
}

// 定义一个接口
type FilterFactory interface {
	Apply(config interface{}) GatewayFilter
	GetOrder() int //排序
}

// 这个是保存像Request，Response这些请求的数据
type ServerWebExchange struct {
	Request *http.Request
}

func BuildServerWebExchange(request *http.Request) *ServerWebExchange {
	return &ServerWebExchange{Request: request}
}

// 用来分隔简单的过滤器
type SimpleFilter string

// 执行
func (filter SimpleFilter) filter() GatewayFilter {
	vList := strings.Split(string(filter), "=")

	if f, ok := FilterMap.Load(vList[0]); ok {
		param := ""
		if len(vList) > 1 {
			param = vList[1]
		}
		return f.(FilterFactory).Apply(param)
	}
	return nil
}

// 获取filterFactory
func (filter SimpleFilter) getClass() FilterFactory {
	vList := strings.Split(string(filter), "=")

	if f, ok := FilterMap.Load(vList[0]); ok {
		return f.(FilterFactory)
	}
	return nil
}

// 对filters进行排序
func (r *Route) sortFilters() {
	r.orderFilters = make([]interface{}, 0)
	for _, f := range r.Filters {
		v := reflect.ValueOf(f)
		if v.Kind() == reflect.String {
			if obj := SimpleFilter(v.String()).getClass(); obj != nil {
				r.orderFilters = append(r.orderFilters, SimpleFilter(v.String()))
			}
		}
	}
	// 排序
	sort.Slice(r.orderFilters, func(i, j int) bool {
		return r.orderFilters[i].(SimpleFilter).getClass().GetOrder() < r.orderFilters[j].(SimpleFilter).getClass().GetOrder()
	})
}

// 过滤器
func (r *Route) Filter(exchange *ServerWebExchange) ResponseFilters {
	rspFilters := make(ResponseFilters, 0)
	//for _, f := range r.Filters {
	//	v := reflect.ValueOf(f)
	//	if v.Kind() == reflect.String {
	//		if simpFilter := SimpleFilter(v.String()).filter(); simpFilter != nil {
	//			simpFilter(exchange)
	//		}
	//	}
	//}
	// 其实这里不用手动设置排序，直接根据配置文件中的顺序。。
	fmt.Println(r.Filters)
	if len(r.orderFilters) == 0 {
		r.sortFilters()
	}
	for _, f := range r.orderFilters {
		rspFilter := f.(SimpleFilter).filter()(exchange)
		if rspFilter != nil {
			rspFilters = append(rspFilters, rspFilter)
		}
	}
	return rspFilters
}
